//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Eas.WebCrawler.Interfaces;

namespace Eas.WebCrawler.Test.Model {
    /// <summary>
    /// Summary description for ChangeQueueTest
    /// </summary>
    [TestClass]
    public class ChangeQueueTest {
        public ChangeQueueTest() {
            //
            // TODO: Add constructor logic here
            //
        }

        Eas.WebCrawler.Model.Core.ChangeQueue _Queue = null;

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize() {
            _Queue = new Eas.WebCrawler.Model.Core.ChangeQueue();
        }
        //
        // Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup() {
            _Queue = null;
        }
        //
        #endregion

        [TestMethod]
        /// <summary>Executes the SimpleTest test.</summary>
        public void SimpleTest() {
            _Queue.EnQueueRequest(Eas.WebCrawler.Interfaces.WorkerState.Paused);
            VerifyValue(WorkerState.Paused);
            VerifyEmpty();
        }

        [TestMethod]
        /// <summary>Executes the MultiAddTest test.</summary>
        public void MultiAddTest() {
            _Queue.EnQueueRequest(WorkerState.Working);
            _Queue.EnQueueRequest(WorkerState.Paused);
            _Queue.EnQueueRequest(WorkerState.Working);
            _Queue.EnQueueRequest(WorkerState.Stopped);
            VerifyAllValues(WorkerState.Working, WorkerState.Paused, WorkerState.Working, WorkerState.Stopped);
            VerifyEmpty();
            VerifyEmpty();
            _Queue.EnQueueRequest(WorkerState.Working);
            VerifyAllValues(WorkerState.Working);
        }

        [TestMethod]
        [ExpectedException(typeof(System.ArgumentOutOfRangeException))]
        /// <summary>Executes the TestSetToUnstarted test, in which the <seealso cref="System.ArgumentOutOfRangeException"/> exception should be thrown during a succesfull test run.</summary>
        public void TestSetToUnstarted() {
            _Queue.EnQueueRequest(WorkerState.Unstarted);
        }


        private void VerifyAllValues(params WorkerState[] values) {
            foreach (WorkerState state in values) {
                VerifyValue(state);
            }
            VerifyEmpty();
        }

        private void VerifyEmpty() {
            Eas.WebCrawler.Interfaces.WorkerState? result = _Queue.DeQueueRequest();
            Assert.IsFalse(result.HasValue);
        }

        private void VerifyValue(WorkerState state) {
            WorkerState? result = _Queue.DeQueueRequest();
            Assert.IsTrue(result.HasValue);
            Assert.AreEqual<WorkerState>(state, result.Value);
        }

    }
}
